
#pragma once

#include <string>
#include <map>

namespace tools {
    class CSocket;
}

typedef std::map<std::string, std::string>  StringMap;

class Http {
public:
    Http(tools::CSocket* sock);
    ~Http();
    void Read(const char * buffer, int len);
    void Reset(void);


    typedef struct {
        enum {
            METHOD_INIT = 0,
            METHOD_GET,
            METHOD_POST,
        } method;
        std::string url;
        std::string proto;
        StringMap   urlpara;
        StringMap   httppara;
        void Reset(void) {
            method = METHOD_INIT;
            url.clear();
            proto.clear();
            urlpara.clear();
            httppara.clear();
        }
    } Param;

    class Scripter {
    public:
        Scripter() {}
        virtual ~Scripter() {}
        virtual void run(Http* http, const std::string& localfile, const Param& para) const = 0;
    };
    
    void Register(std::string ext, const Scripter* sc);
    void RegisterDefaultScripter(const Scripter* sc);

    void Reply404(void);
    void Reply(int code, const char * content, int len);
    
    std::string MakeHttpHead(int code, int ContextLength);
    Param&  GetParam(void) { return para_; }

private:
    int ParseHead(char * buffer);
    void Reply(const char * content, int len);

    void OnRequest(const char * content, int len);

private:
    tools::CSocket* sock_;

    char *  buffer;
    int     buflen;
    std::map<int, const char *>  codemap;

    Param   para_;

    std::map<std::string, const Scripter*>    scripter_map_;
    const Scripter * default_scripter_;
};



